﻿using NativeWifi;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Net;
using System.Net.NetworkInformation;
using System.Text;
using System.Windows.Forms;
using VNet.VisiSuite.Common.Logger;

namespace VNet.VisiSuite.VisiBoard.WebServer
{
    class SystemInfo
    {
        private static string _version;
        private static string _cell_name;
        private static bool _offline = false;
        private const string NoSystemBattery = "No system battery";
        private const string Unavailable = "Unavailable";

        public static string version()
        {
            return _version;
        }

        public static void version(string ver)
        {
            _version = ver;
        }

        public static string cellName()
        {
            return _cell_name;
        }

        public static void cellName(string name)
        {
            _cell_name = name;
        }

        public static bool offline()
        {
            return _offline;
        }

        public static void offline(bool offline)
        {
            _offline = offline;
        }

        public static bool isRunningOnMono()
        {
            return Type.GetType("Mono.Runtime") != null;
        }

        public static DateTime lastReboot()
        {
            var ticks = Stopwatch.GetTimestamp();
            var uptime = ((double)ticks) / Stopwatch.Frequency;
            return DateTime.Now.AddSeconds(-1 * uptime);
        }

        public static int wifiSignalQuality(out int dbm)
        {
            int quality = 0;
            dbm = 0;

            if (isRunningOnMono())
            {

                try
                {
                    int cnt = 0;
                    string line;

                    // Read the file and display it line by line.
                    var file = new System.IO.StreamReader("/proc/net/wireless");
                    while ((line = file.ReadLine()) != null)
                    {
                        ++cnt;
                        if (cnt == 3)
                        {
                            char[] delimiters = new char[] { ' ', '\t' };
                            string[] data = line.Trim().Split(delimiters, StringSplitOptions.RemoveEmptyEntries);
                            /**
                            for (int ii = 0; ii < data.Length; ++ii)
                            {
                                log(ii.ToString() + ": " + data[ii]);
                            }
                            **/
                            if (data.Length > 3)
                            {
                                dbm = (int)Math.Round(Convert.ToDouble(data[3]));
                                if (dbm < 0)
                                    quality = (int)Math.Round(Convert.ToDouble(data[2]) * 100.0 / 70.0);
                                else
                                    quality = (int)Math.Round(Convert.ToDouble(data[2]));
                            }
                            break;
                        }
                    }

                    file.Close();
                }
                catch (Exception ex)
                {
                    FileLog.Error("wifiSignalQuality() - ", ex);
                }

            }
            else
            {
                try
                {
                    // Loop through all network interface to check if current computer has wifi connection
                    NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                    foreach (NetworkInterface adapter in nics)
                    {
                        if (adapter.OperationalStatus == OperationalStatus.Up)
                        {
                            if (adapter.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
                            {
                                WlanClient client = new WlanClient();
                                var firstWlanInterface = client.Interfaces[0];
                                quality = (int)firstWlanInterface.CurrentConnection.wlanAssociationAttributes.wlanSignalQuality;
                                dbm = firstWlanInterface.RSSI;
                            }
                        }
                    }
                }
                catch(Exception ex)
                {
                    FileLog.Error("wifiSignalQuality() - ", ex);
                }
            }
            
            return quality;
        }

        public static string hostname()
        {
            return Dns.GetHostName();
        }

        public static string ipAddress()
        {
            IPHostEntry host;
            string address = "?";
            host = Dns.GetHostEntry(Dns.GetHostName());
            foreach (IPAddress ip in host.AddressList)
            {
                if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
                {
                    address = ip.ToString();
                }
            }
            return address;
        }

        public static string BatteryPercentage()
        {
            PowerStatus p = SystemInformation.PowerStatus;
            if (p.BatteryChargeStatus != BatteryChargeStatus.NoSystemBattery)
                return string.Format("{0} %", p.BatteryLifePercent * 100);
            else
                return NoSystemBattery;
        }

        public static string BatteryLife()
        {
            PowerStatus p = SystemInformation.PowerStatus;
            if (p.BatteryChargeStatus != BatteryChargeStatus.NoSystemBattery)
            {
                // -1 indicate windows is unable to estimate time remaining
                // powerline status online mean the machine is plugged to power source
                // on both cases, set Unavailable to battery life remaining.
                if (p.BatteryLifeRemaining == -1 || p.PowerLineStatus == PowerLineStatus.Online)
                {
                    return Unavailable;
                }
                else
                {
                    var timespanRemaining = new TimeSpan(0, 0, p.BatteryLifeRemaining);
                    return timespanRemaining.ToString(@"hh\:mm");
                }
            }
            else
                return NoSystemBattery;
        }

        public static string BatteryCharging()
        {
            PowerStatus p = SystemInformation.PowerStatus;
            if (p.BatteryChargeStatus != BatteryChargeStatus.NoSystemBattery)
            {
                return p.PowerLineStatus == PowerLineStatus.Online ? "Yes" : "No";
            }
            else
                return NoSystemBattery;
        }

    }
}
